<?php

namespace app\api\controller\v49;

use app\aliyun\controller\AliyunFilterWordV2;
use app\api\controller\v2\Auth;
use app\common\cachemodel\AppConfig;
use app\common\cachemodel\chat\call\HzCallChatLastSendTimeRecord;
use app\common\cachemodel\chat\call\HzCallChatRecord;
use app\common\cachemodel\chat\call\HzCallChatRecordDetails;
use app\common\cachemodel\chat\HzChatRecordDetails;
use app\common\cachemodel\chat\HzChatRecordDetailsReport;
use app\common\lib\Aes;
use app\common\lib\Util;
use app\common\model\Recode;
use app\common\service\ChatParse;
use think\Db;
use think\Log;

class AiCallChat extends Auth
{
    /**
     * 获取 聊天列表
     * @return \think\response\Json
     * @throws \Exception
     */
    public function getChatIdList()
    {
        $hzCallChatRecordmodel = new HzCallChatRecord();

        $pageData = $hzCallChatRecordmodel->getListPage($this->user['id'], 'update_time', [], 0, 'desc', 0);

        $pageData['data'] = $hzCallChatRecordmodel->pageDataResert($pageData['data']);

        return show(config('code.success'), '请求成功', $pageData);
    }

    /**
     * 删除 聊天对话记录
     * @return \think\response\Json
     * @throws \Exception
     */
    public function delChatId()
    {
        $rid = input('rid/d', -1);
        if ($rid === -1)
        {
            return show(config('code.error'), '服务异常，档案不存在');
        }
        if ($rid === 0 && $this->user['rid'])
        {
            return show(config('code.error'), '服务异常，档案不存在');
        }
        $hzCallChatRecordModel = new HzCallChatRecord();
        if ($rid)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
            if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'])
            {
                return show(config('code.error'), '服务异常，档案不存在');
            }
            $chatId = $hzCallChatRecordModel->getChatIdByRid($rid);
        } else
        {   // 没有自己的档案
            $chatId = $hzCallChatRecordModel->getChatIdByUid($this->user['id']);
        }
        if (!$chatId)
        {
            return show(config('code.success'), '会话记录已删除');
        }
        $res = $hzCallChatRecordModel->delChat($this->user['id'], $rid, $chatId);
        if ($res)
        {
            if ($rid === $this->user['rid'])
            {   // 删除用户自己的会话
                (new HzCallChatLastSendTimeRecord())->UpdateData($this->user['id'], ['chat_id' => 0]);
            }
            return show(config('code.success'), '操作成功');
        } else
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
    }

    /**
     * 获取对话详情
     * @return \think\response\Json
     */
    public function getCharDetails()
    {
        $rid = input('rid/d', 0);
        $rid2 = input('rid2/d', 0);
        $minId = input('min_id/d', 0);
        $hzCallChatRecordDetailsModel = new HzCallChatRecordDetails();
        $chatConfig = (new AppConfig())->configInfo('chat_config');
        $vipFreeNum = $chatConfig['vip_free_num_today'] ?? 5;
        $recodeInfo = null;
        $rid = $rid ?: (int)($this->user['rid'] ?? 0);
        if ($rid)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
            if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'] || $recodeInfo['status'] != 1)
            {
                return show(config('code.error'), '服务异常，档案不存在');
            }

            if ($rid2 > 0 && $rid === $rid2)
            {
                $rid2 = -1;
            }
        } else
        {
            $rid2 = 0;
        }
        if ($rid2 > 0)
        {
            $recodeInfo2 = (new Recode())->getRecode(['id' => $rid2]);
            if (!$recodeInfo2 || $recodeInfo2['uid'] != $this->user['id'] || $recodeInfo2['status'] != 1)
            {
                return show(config('code.error'), '服务异常，档案不存在');
            }
        }
        $hzCallChatRecordModel = new HzCallChatRecord();
        // 通过rid 取当前会话ID
        if ($rid)
        {   // 有自己的档案
            $chatId = $hzCallChatRecordModel->getChatIdByRid($rid);
        } else
        {   // 没有自己的档案 437
            $chatId = $hzCallChatRecordModel->getChatIdByUid($this->user['id']);
        }
        if ($chatId)
        {   // 有会话记录  取当前的会话记录
            $resData = $hzCallChatRecordDetailsModel->getPageDatas($chatId, 10, $minId);
            $chatData = $hzCallChatRecordModel->getInfoById($chatId);
            if ($rid2 === -1)
            {
                $rid2 = 0;
                if (!isset($chatData['rid2']) || $chatData['rid2'] !== 0)
                {
                    $hzCallChatRecordModel->updateData($chatId, $this->user['id'], ['rid2' => 0]);
                }
            } else
            {
                if ($rid2 > 0 && (!isset($chatData['rid2']) || $rid2 !== $chatData['rid2']))
                {
                    $hzCallChatRecordModel->updateData($chatId, $this->user['id'], ['rid2' => $rid2]);
                } else
                {
                    $rid2 = $chatData['rid2'] ?? 0;
                    $recodeInfo2 = (new Recode())->getRecode(['id' => $rid2]);
                    if (!$recodeInfo2 || $recodeInfo2['uid'] != $this->user['id'] || $recodeInfo2['status'] != 1)
                    {   // 副档案 已删除 或不存在
                        $hzCallChatRecordModel->updateData($chatId, $this->user['id'], ['rid2' => 0]);
                        $rid2 = 0;
                    }
                }
            }
        } else
        {   // 没有会话记录 创建新的会话
            $nowTimw = $this->request->time();
            $rid2 = max($rid2, 0);
            $insertData = [
                'uid' => $this->user['id'],
                'rid' => $rid,
                'rid2' => $rid2,
                'last_chat_detail_id' => 0,
                'last_chat_detail_time' => 0,
                'create_time' => $nowTimw,
                'update_time' => $nowTimw,
            ];
            if (Util::commentCheck($this->user['id'], ['action' => 'AiChat.getCharDetails', 'uid' => $this->user['id'], 'rid' => $rid], 2))
            {   // 操作频繁 请稍后再试～
                return show(config('code.error'), '');
            }
            // 创建新的会话
            $chatId = $hzCallChatRecordModel->initSave($insertData);
            // 记录 自己的档案 用户会话 ID 信息
            if ($rid === 0 || $rid === $this->user['rid'])
            {   // 没有自己的档案 或者 自己的档案
                (new HzCallChatLastSendTimeRecord())->UpdateData($this->user['id'], ['chat_id' => $chatId]);
            }
            $resData = [
                'total' => 0,
                'surplus_num' => 0,
                'data' => [],
            ];
        }
        if ($resData['data'])
        {
            $resData['data'] = $hzCallChatRecordDetailsModel->dataListResert($resData['data'], false);
        }
        $resData['avatar'] = $recodeInfo ? $recodeInfo['avatar'] : '';
        // 剩余 会话 次数
        $numData = $hzCallChatRecordDetailsModel->getChatQueryEndNumRes($this->user['id']);    //  剩余对话次数
        $resData['num'] = $numData['res_num'];
        $resData['vip_recommend'] = $numData['vip_level'] > 0 ? null : [
            'tip' => '小行星会员每日可免费提问' . $vipFreeNum . '次',
            'btn_name' => '现在开通',
        ];
        $resData['rid'] = $rid;
        $resData['rid2'] = $rid2;
        $resData['call_avatar'] = '/test/consult_chat/call_avatar.png';
        $resData['call_nickname'] = '莫小奇';

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 发送对话
     */
    public function sendQuestion()
    {
        $rid = input('rid/d', 0);
        $question = input('question/s', '');
        $gptModel = input('model/s', '');   // 会话模型
        $url = input('url/s', '');   // 语音地址
        $duration = input('duration/d', 0);   // 语音时长
        if (Util::commentCheck($this->user['id'], ['action' => 'AiCallChat.sendQuestion', 'question' => $question, 'rid' => $rid, 'url' => $url], 3) && (int)$this->user['id'] != 10834769)
        {//mark 17333657763 手机号的uid为10834769，可以测试并发
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }
        if (empty($question))
        {
            return show(config('code.error'), '请输入提问的内容');
        }
        if (mb_strlen($question) > 200)
        {
            return show(config('code.error'), '服务异常');
        }
        if ($duration > 30)
        {
            return show(config('code.error'), '服务异常,录音时长过长～');
        }
        $aliRes = AliyunFilterWordV2::checkAIText($question);
        if ($aliRes['status'] === false)
        {
            return show(0, '检测到敏感内容');
        }
        $recodeInfo = null;
        if ($rid)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
            if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'] || $recodeInfo['status'] != 1)
            {
                return show(config('code.error'), '档案不存在');
            }
        } else
        {
            $rid = (int)($this->user['rid'] ?? 0);
        }

        $hzCallChatRecordModel = new HzCallChatRecord();
        $hzCallChatRecordDetailsModel = new HzCallChatRecordDetails();
        $numData = $hzCallChatRecordDetailsModel->getChatQueryEndNumRes($this->user['id']);
        if ($numData['res_num'] <= 0)
        {   // 会话次数 用尽
            return show(config('code.error'), '今日提问机会用尽，明天再来吧～');
        }
        // // 是否是付费用户 是vip 或者 有付费次数 或者 有 赠送次数
        // $isPayingUser = $numData['vip_level'] > 0 || $numData['pay_num'] > 0 || $numData['admin_num'] > 0;
        // if (!$isPayingUser && $hzCallChatRecordDetailsModel->getIsFullLoad())
        // {   // 不是付费用户
        //     return show(config('code.error'), '当前体验人数过多，请稍后重试～');
        // }
        // 通过rid 取当前会话ID
        if ($rid)
        {
            $chatId = $hzCallChatRecordModel->getChatIdByRid($rid);
        } else
        {
            $chatId = $hzCallChatRecordModel->getChatIdByUid($this->user['id']);
        }
        if (!$chatId)
        {
            return show(config('code.error'), '服务异常，请刷新页面重试～');
        }
        // 有档案情况
        if ($rid && !$recodeInfo)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
        }
        if (Util::isOnline())
        {   // 线上环境
            $chatConfig = (new AppConfig())->configInfo('chat_config');
            $gptModel = $chatConfig['gpt_model_name'] ?? '';
        }
        $chatData = $hzCallChatRecordModel->getInfoById($chatId);
        if (isset($chatData['rid2']) && $chatData['rid2'])
        {
            $recodeInfo2 = (new Recode())->getRecode(['id' => $chatData['rid2']]);
        }
        // 去 解析 输入内容的结果
        $queryResult = ChatParse::getCallQuestionParse($question, $recodeInfo, $chatId, $gptModel, $recodeInfo2 ?? null);
        // 旧版本返回格式【小于2.10.4】 {"success":true,"data":{"code":200,"message":"\u6210\u529f","data":{"type":2,"response":{"id":"","standsentence":"","constellation":""},"topsentence":[],"answer":"","default_answer_id":-1,"model_name":"ChatGLM-6b-LoRa-V10","semantic_answer_scene":0,"semantic_answer_cls_tools":[1,0,"afa109e1-4058-4f58-9158-cde151ab0a43",7,0,[]],"recommend_type":1,"city_type":0,"is_current_session_valid":1,"is_show_need_record_hint":0,"stream":1},"use_time":""},"question":"\u6211\u4eec\u4f1a\u5728\u4e00\u8d77\u5417"}
        if ($queryResult['success'])
        {
            if ($queryResult['data']['code'] === 200)
            {   // 语义解析成功
                $queryResult['data']['data']['use_time'] = $queryResult['data']['use_time'];
                $result = $queryResult['data']['data'];
            } else
            {   // 解析失败
                $this->setQueryLog($chatId, 0, $queryResult);

                if (isset($queryResult['data']['data']['type']) && $queryResult['data']['data']['type'] == 4)
                {
                    return show(202, '包含违规内容，请修改');
                }
                return show(config('code.error'), '服务异常，请稍后再试～');
            }
        } else
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . "()  Curl请求python语义解析异常：errorCode:{$queryResult['errorCode']} ;errorMessage:{$queryResult['errorMessage']}", 'error', true);
            $this->setQueryLog($chatId, 0, $queryResult);
            return show(config('code.error'), '服务异常，请稍后再试～');
        }

        $nowTimw = $this->request->time();
        $insertData = [
            [   // 用户提问消息
                'chat_id' => $chatId,
                'uid' => $this->user['id'],
                'rid' => $rid,
                'type' => 2,    //  1=>APP消息 2=>用户发送消息
                'title' => '',
                'content' => $question, // 提问问题
                'url' => $url,
                'data_type' => 1,
                'extend' => ['duration' => $duration],  // call_text_type = 0 表示 随机内容 非固定文案
                'result_data' => '',
                'option_id' => '',
                'pid' => 0,
                'create_time' => $nowTimw,
            ],
        ];
        if (isset($queryResult['history']) && $queryResult['history'] && isset($result['science_dice']) && $result['science_dice'] === 1)
        {   // 强制 开始 骰子
            $historyData = $queryResult['history'][count($queryResult['history']) - 1];
            // 获取 骰子问题
            $diceQuestion = $historyData['question'];
            // 扣除次数
            $numData = $hzCallChatRecordDetailsModel->chatQueryEndNumDec($this->user['id'], $numData);
            $_arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 16];// 行星id随机数种子`
            $insertData[] = [
                'chat_id' => $chatId,
                'uid' => $this->user['id'],
                'rid' => $rid,
                'type' => 1,    //  1=>APP消息 2=>用户发送消息
                'title' => '',
                'content' => '', // 提问问题
                'url' => '',
                'data_type' => 3,   // 1=>普通消息  2=>结果消息 3=>扩展消息'
                'extend' => [
                    'result_type' => 2,
                    'model_name' => $gptModel,
                    'is_valid' => 1,
                    'stream' => 1,
                    'sas' => 3, // 语义解析集群分类场景结果 0为专业场景，1为基础场景，2为拒答场景 3未进行语义解析之间进行骰子获取结果
                    'sact' => [],
                    'dice_info' => [
                        'question' => $diceQuestion,
                        'planet' => $_arr[rand(0, count($_arr) - 1)],
                        'sign' => rand(1, 12),
                        'house' => rand(1, 12),
                        'id' => 0,
                        'answer_type' => 2,
                        'answer_content' => '',
                    ],
                ],
                'result_data' => '',
                'option_id' => '',
                'num_type' => $numData['use_type'], // 使用类型 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
                'pid' => 0, // 待更新
                'create_time' => $nowTimw,
            ];
            $stream = 1;
        } else
        {
            // 是否 有效【收费】
            $isValid = isset($result['is_current_session_valid']) && $result['is_current_session_valid'] === 1 ? 1 : 0;
            if ($isValid && $result['type'] === 2 && isset($result['is_combining']) && $result['is_combining'] === 1 && (!isset($chatData['rid2']) || !$chatData['rid2']))
            {
                $isValid = 0;
            }
            // 扣除 提问 次数
            if ($isValid)
            {   // 会话次数 -1
                $numData = $hzCallChatRecordDetailsModel->chatQueryEndNumDec($this->user['id'], $numData);
            }
            $stream = $result['stream'];
            switch ($result['type'])
            {
                case 2: // 闲聊
                    $data_type = 1;
                    $extend = [
                        'result_type' => 2,
                        'model_name' => $result['model_name'] ?? '',
                        'is_valid' => $isValid,
                        'stream' => $result['stream'],
                    ];
                    if (isset($result['is_show_need_record_hint']) && (int)$result['is_show_need_record_hint'] === 1)
                    {   //如果python返回需要提示用户添加档案的话，返回数据的数据格式是添加档案
                        $data_type = 3;
                        $extend = ['add_recode' => 1, 'model_name' => $result['model_name'] ?? '', 'is_valid' => 0];
                    } else
                    {
                        $extend['sas'] = $result['semantic_answer_scene'];    // semantic_answer_scene   语义解析集群分类场景结果 当stream为1，并且回调流式接口才会返回 示例 0=>专业，1=>基础，2=>拒答
                        $extend['sact'] = $result['semantic_answer_cls_tools'];   // semantic_answer_cls_tools   语义解析集群分类工具结果 当stream为1，并且回调流式接口才会返回 示例 [0,0] 第一个元素为api_bot接口返回的recommend_type值，第2个元素为api_bot接口返回的city_type值
                        // 0=>人称对齐  1=>主档案未对齐    2=>副档案未对齐 【未对齐时不消耗次数】
                        $isCombiningClear = (int)($result['is_combining_clear'] ?? 0);
                        if (isset($result['is_combining']) && $result['is_combining'] === 1)
                        {   // 合盘情况
                            if (isset($chatData['rid2']) && $chatData['rid2'])
                            {   // 直接进行合盘
                                $recodeInfo2 = (new Recode())->getRecode(['id' => $chatData['rid2']]);
                                if ($isCombiningClear === 0)
                                {   // 人称对齐 进行 合盘
                                    $extend['synastry_result'] = [
                                        'rid' => $rid,
                                        'rname1' => $recodeInfo['name'],
                                        'rid2' => $chatData['rid2'],
                                        'rname2' => $recodeInfo2['name'],
                                        'question' => $question,
                                    ];
                                } else
                                {   // 推荐 合盘 澄清插件
                                    $data_type = 3;
                                    $extend['recommend_synastry'] = [
                                        'rid2' => $chatData['rid2'],
                                        'status' => 0,  // 0=>等待用户是否合盘 1=>合盘选择成功 2=>暂不合盘继续解答
                                        'avatar1' => $recodeInfo['avatar'],
                                        'avatar2' => $recodeInfo2['avatar'],
                                        'name1' => $recodeInfo['name'],
                                        'name2' => $recodeInfo2['name'],
                                        'is_combining_clear' => $isCombiningClear, // 对齐   1=>主档案未对齐    2=>副档案未对齐 【未对齐时不消耗次数】
                                        'type' => 2,    // 插件模式 1=>单盘情况  2=>合盘情况
                                    ];
                                    $extend['stream'] = 0;
                                    $isValid = 0;
                                    $stream = 0;
                                }
                            } else
                            {   // 推荐 合盘 插件  本次不扣次数
                                $data_type = 3;
                                $extend['recommend_synastry'] = [
                                    'rid2' => 0,
                                    'status' => 0,  // 0=>等待用户是否合盘 1=>合盘选择成功 2=>暂不合盘继续解答
                                    'avatar1' => $recodeInfo['avatar'],
                                    'name1' => $recodeInfo['name'],
                                    'not_combining_has_answer' => $result['not_combining_has_answer'],  // 选择暂不合盘时，0=>没有流式答案，只推荐插件功能【不记次数】   1=>通过流式获取答案，可能推荐其他插件【记次数】
                                    'type' => 1,    // 插件模式 1=>单盘情况  2=>合盘情况
                                ];
                                $extend['stream'] = 0;
                                $isValid = 0;
                                $stream = 0;
                            }
                        } else
                        {   // 单盘情况
                            if ($isCombiningClear && isset($chatData['rid2']) && $chatData['rid2'])
                            {   // 档案 未对齐
                                if ($isCombiningClear === 2)
                                {   // 副档案 未对齐
                                    $recodeInfo2 = (new Recode())->getRecode(['id' => $chatData['rid2']]);
                                    $ridItem = $chatData['rid2'];
                                    $avatar = $recodeInfo2['avatar'];
                                    $name = $recodeInfo2['name'];
                                } else
                                {   // 主档案 未对齐
                                    $ridItem = $rid;
                                    $avatar = $recodeInfo['avatar'];
                                    $name = $recodeInfo['name'];
                                }
                                $data_type = 3;
                                $extend['recode_choose'] = [
                                    'rid' => $ridItem,
                                    'status' => 0,  // 0=>等待用户确认解答 1=>已解答 2=>未解答
                                    'avatar' => $avatar,
                                    'name' => $name,
                                    'is_combining_clear' => $isCombiningClear, // 对齐   1=>主档案未对齐    2=>副档案未对齐 【未对齐时不消耗次数】
                                ];
                                $extend['stream'] = 0;
                                $isValid = 0;
                                $stream = 0;
                            }
                        }
                    }
                    $insertData[] = [   // 用户提问消息
                        'chat_id' => $chatId,
                        'uid' => $this->user['id'],
                        'rid' => $rid,
                        'type' => 1,    //  1=>APP消息 2=>用户发送消息
                        'title' => '',
                        'content' => $stream === 0 ? $result['answer'] : '', // 提问问题
                        'url' => '',
                        'data_type' => $data_type,   // 1=>普通消息  2=>结果消息 3=>扩展消息
                        'extend' => $extend,  //  澄清数据
                        'result_data' => '',
                        'num_type' => $isValid ? $numData['use_type'] : 0, // 使用类型0=>不扣次数 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
                        'option_id' => '',
                        'pid' => 0, // 待更新
                        'create_time' => $nowTimw,
                    ];
                    break;
                default:
            }
        }
        $resData = $hzCallChatRecordDetailsModel->SaveData($chatId, $insertData);
        if ($resData)
        {   // 发送成功
            // 更新 用户 最后发送消息 时间
            (new HzCallChatLastSendTimeRecord())->UpdateData($this->user['id'], ['last_send_time' => $nowTimw]);
            $chatDetailId = $resData[0]['id'];
            $hzCallChatRecordModel->updateData($chatId, $this->user['id'], [
                'last_chat_detail_id' => $chatDetailId,
                'last_chat_detail_time' => $nowTimw,
            ]);
            $this->setQueryLog($chatId, $chatDetailId, $queryResult);
            unset($resData[0]); // 只返回答案信息
            $resData = $hzCallChatRecordDetailsModel->dataListResert($resData);
            if (isset($resData[0]))
            {
                if ($resData[0]['is_stream_reload'] === 1)
                {
                    $resData[0]['is_stream_reload'] = 0;
                    $resData[0]['content'] = '';
                }
                $resData[0]['create_time'] = '';
                $resData[0]['stream'] = $stream;
                $resData[0]['num'] = $numData['res_num'];
            }
            return show(config('code.success'), '请求成功', $resData[0]);
        } else
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
    }

    /**
     * 记录 语义解析 日志
     * @param int $chatId
     * @param $chatDetailId
     * @param array $queryResult
     * @return void
     */
    public function setQueryLog(int $chatId, $chatDetailId, array $queryResult): void
    {
        Db::table('wechat_backup_07_18_14_43_00.hz_call_chat_python_result_log')->insert(['chat_id' => $chatId, 'chat_record_id' => $chatDetailId, 'result' => json_encode($queryResult, JSON_UNESCAPED_UNICODE), 'create_time' => time()]);
    }

    /**
     * 获取 流式回复结果
     */
    public function getQuestionAnswerStream()
    {
        $rid = input('rid/d', 0);
        $chatDetailId = input('chat_id/d', 0);
        $gptModel = input('model/s', '');   // 会话模型
        if (Util::commentCheck($this->user['id'], ['action' => 'getQuestionAnswerStream', 'chat_id' => $chatDetailId, 'rid' => $rid], 3) && (int)$this->user['id'] != 12346744)
        {
            return '';
        }
        $recodeInfo = null;
        if ($rid)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
            if (!$recodeInfo || $recodeInfo['uid'] != $this->user['id'])
            {
                return '';
            }
        } else
        {
            $rid = (int)($this->user['rid'] ?? 0);
        }

        $hzCallChatRecordModel = new HzCallChatRecord();
        $hzCallChatRecordDetailsModel = new HzCallChatRecordDetails();
        // 通过rid 取当前会话ID
        if ($rid)
        {
            $chatId = $hzCallChatRecordModel->getChatIdByRid($rid);
        } else
        {
            $chatId = $hzCallChatRecordModel->getChatIdByUid($this->user['id']);
        }
        if (!$chatId)
        {
            return '';
        }
        // 有档案情况
        if ($rid && !$recodeInfo)
        {
            $recodeInfo = (new Recode())->getRecode(['id' => $rid]);
        }
        $chatData = $hzCallChatRecordModel->getInfoById($chatId);
        $rid2 = $chatData['rid2'] ?? 0;
        if (Util::isOnline())
        {   // 线上环境
            $chatConfig = (new AppConfig())->configInfo('chat_config');
            $gptModel = $chatConfig['gpt_model_name'] ?? '';
        }
        $chatDetailInfo = $hzCallChatRecordDetailsModel->getInfoById($chatDetailId);
        if (isset($chatDetailInfo['extend']['dice_info']))
        {
            $isDice = 1;
            $planet = $chatDetailInfo['extend']['dice_info']['planet'] ?? 0;
            $sign = $chatDetailInfo['extend']['dice_info']['sign'] ?? 1;
            $house = $chatDetailInfo['extend']['dice_info']['house'] ?? 1;
            $planetName = (new Util())->PlanetTypeName($planet);
            $signConfig = config('astro.sign_name');

            $diceInfo = [
                'dice_planet' => $planetName,
                'dice_sign' => $signConfig[$sign],
                'dice_house' => $house . '宫',
            ];
            $question = $chatDetailInfo['extend']['dice_info']['question'] ?? '';
        } elseif (isset($chatDetailInfo['extend']['synastry_result']))
        {
            $question = $chatDetailInfo['extend']['synastry_result']['question'] ?? '';
            $rid2 = $chatDetailInfo['extend']['synastry_result']['rid2'];
            $recodeInfo['name'] = $chatDetailInfo['extend']['synastry_result']['rname1'] ?? '';
            $rname2 = $chatDetailInfo['extend']['synastry_result']['rname2'] ?? '';
            $isCombining = 1;
        } elseif (isset($chatDetailInfo['extend']['recode_choose_result']))
        {
            $question = $chatDetailInfo['extend']['recode_choose_result']['question'] ?? '';
            $rid2 = 0;
            $recodeInfo = (new Recode())->getRecode(['id' => $chatDetailInfo['extend']['recode_choose_result']['rid']]);
        } else
        {
            $parentData = $hzCallChatRecordDetailsModel->getInfoById($chatDetailInfo['pid'], ['content', 'extend', 'pid']);
            if (isset($parentData['extend']['recommend_synastry']) && $parentData['pid'])
            {
                $parentData1 = $hzCallChatRecordDetailsModel->getInfoById($parentData['pid'], ['content']);
                $question = $parentData1['content'] ?? '';
            } else
            {
                $question = $parentData['content'] ?? '';
            }
        }
        if ($rid2 && !isset($rname2))
        {
            $recodeInfo2 = (new Recode())->getRecode(['id' => $rid2]);
            $rname2 = $recodeInfo2['name'] ?? '';
        }
        $isConsum = 0;
        if (isset($chatDetailInfo['num_type']) && $chatDetailInfo['num_type'])
        {
            if ($chatDetailInfo['num_type'] === 1)
            {   // 免费次数
                $numData = $hzCallChatRecordDetailsModel->getChatQueryEndNumRes($this->user['id']);
                if ($numData['vip_level'] > 0 || $numData['pay_num'] > 0 || $numData['admin_num'] > 0)
                {
                    $isConsum = 1;
                }
            } else
            {   // 付费次数
                $isConsum = 1;
            }
        }
        // 去 解析 输入内容的结果
        $queryStr = ChatParse::getCallQuestionParseStreamData($question, $recodeInfo, $chatId, $chatDetailId, $gptModel, [
            'semantic_answer_scene' => $chatDetailInfo['extend']['sas'],
            'semantic_answer_cls_tools' => $chatDetailInfo['extend']['sact'],
            'is_dice' => $isDice ?? 0,
            'dice_info' => $diceInfo ?? null,
            'is_consum' => $isConsum,
            'rid1' => $rid2,
            'rid1_name' => $rname2 ?? '',
            'is_combining' => $isCombining ?? 0,
        ]);

        $chatDetailInfo['extend']['stream'] = 2;
        $queryStr = str_replace("￥", "", $queryStr);
        $answerViolation = false;
        if (strpos($queryStr, 'θ') !== false)
        {
            $answerViolation = true;
            $queryStr = '准准认为你的问题包含敏感信息，换个问题再试试吧。';
            $chatDetailInfo['extend']['answer_violation'] = 1;  // 答案违规
        }
        if (isset($isDice) && $isDice)
        {
            $chatDetailInfo['extend']['dice_info']['answer_content'] = $queryStr;
        }
        $upData = ['content' => $queryStr, 'extend' => json_encode($chatDetailInfo['extend'], JSON_UNESCAPED_UNICODE)];
        if ($answerViolation && isset($chatDetailInfo['num_type']) && $chatDetailInfo['num_type'])
        {   //问题违规  本次对话消耗次数 将次数还原
            $upData['num_type'] = 0;
            (new HzChatRecordDetails())->chatQueryEndNumInc($this->user['id'], $chatDetailInfo['num_type']);
        }
        // 更新结果
        $hzCallChatRecordDetailsModel->UpdateData($chatDetailId, $upData);
    }

    public function uploadAnswerAudio()
    {
        $chatDetailId = input('chat_id/d', 0);
        $url = input('url/s', '');   // 语音地址
        $duration = input('duration/d', 0);   // 语音时长
        if (!$chatDetailId || empty($url) || !$duration)
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $hzCallChatRecordDetailsModel = new HzCallChatRecordDetails();
        $chatDetailInfo = $hzCallChatRecordDetailsModel->getInfoById($chatDetailId);
        if (!$chatDetailInfo || $chatDetailInfo['uid'] !== $this->user['id'] || $chatDetailInfo['type'] !== 1)
        {
            return show(config('code.error'), '服务异常，数据不存在～');
        }

        $chatDetailInfo['extend']['duration'] = $duration;

        $updateData = [
            'url' => $url,
            'extend' => json_encode($chatDetailInfo['extend'], JSON_UNESCAPED_UNICODE),
        ];

        $hzCallChatRecordDetailsModel->UpdateData($chatDetailId, $updateData);

        return show(config('code.success'), '上传成功');
    }

    public function getChatTts()
    {
        $chatDetailId = input('chat_id/d', 0);
        $text = input('text/s', '');
        $hzChatRecordDetailsModel = new HzCallChatRecordDetails();
        if (!$chatDetailId)
        {
            // return show(config('code.error'), '请求异常，请稍后再试～');
            return;
        }
        $text = (new Aes())->decryptWithOpenssl($text);
        if (empty($text))
        {
            return;
        }
        //验证是否重复操作
        if (Util::commentCheck($this->user['id'], ['action' => 'getChatVoice', 'chat_detail_id' => $chatDetailId, 'text' => $text], 2))
        {
            return;
            // return show(config('code.error'), '别心急，等一等');
        }
        $chatDetailInfo = $hzChatRecordDetailsModel->getInfoById($chatDetailId);
        if (!$chatDetailInfo || $chatDetailInfo['uid'] !== $this->user['id'])
        {
            return;
            // return show(config('code.error'), '服务异常，请稍后再试～');
        }
        if (empty($chatDetailInfo['content']) && empty($text))
        {
            return;
        }

        if ($text)
        {
            ChatParse::getChatTTS([
                'text' => $text,
                'uid' => $this->user['id'],
            ]);
        }
    }

    /**
     * 举报
     */
    public function report()
    {
        $chatDetailId = input('chat_id/d', 0);
        $reason = input('reason/s', '');

        if (!$chatDetailId || (!$reason && $reason !== "0"))
        {
            return show(config('code.error'), '请求异常，请稍后再试');
        }
        if (!Util::IsIos() && Util::checkAppVersion('2.10.6') === '小')
        {   // 安卓  并且 版本 低于2.10.6
            $chatDetailId += 1000000;
        }
        //验证是否重复操作
        if (Util::commentCheck($this->user['id'], ['action' => 'call_chat_report', 'chat_detail_id' => $chatDetailId, 'reason' => $reason,]))
        {
            return show(config('code.error'), '别心急，等一等');
        }

        $reasonArr = explode(',', $reason);
        foreach ($reasonArr as $rid)
        {
            /**
             * 举报原因
             * 0 => 存在广告营销信息
             * 1 => 涉嫌黄、赌、毒等违规内容
             * 2 => 侵害他人权益及隐私
             * 3 => 不良传导，价值观扭曲
             * 4 => 传播不实信息，内容失实
             * 5 => 其他原因
             */

            if (!in_array($rid, [0, 1, 2, 3, 4, 5]))
            {
                return show(config('code.error'), '请求异常，请稍后再试');
            }
        }

        $hzChatRecordDetailsModel = new HzCallChatRecordDetails();
        $chatDetailInfo = $hzChatRecordDetailsModel->getInfoById($chatDetailId);
        if ($chatDetailInfo['uid'] !== $this->user['id'])
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }

        (new HzChatRecordDetailsReport())->setReport($this->user['id'], $chatDetailId, $reason, 2);

        return show(config('code.success'), '举报成功');
    }
}
